#include <algorithm>
#include "EpilExpressionInterpreter.h"
#include "EpilExpressionListInterpreter.h"
#include "EpilPointerHelper.h"

using namespace std;


EpilExpressionListInterpreter::EpilExpressionListInterpreter( EpilInterpreter * interpreter )
: EpilInterpreterBase( interpreter )
{
}


void EpilExpressionListInterpreter::Run( const EpilExpressionCodeList & code )
{
	if( code.empty() )
	{
		return;
	}

	EpilExpressionCodeList::const_iterator itLast = code.end();
	--itLast;

	for( EpilExpressionCodeList::const_iterator it = code.begin(); it != itLast; ++it )
	{
		EpilExpressionInterpreter ei( this->GetInterpreter() );
		try
		{
			ei.Run( *it );
		}
		catch( ... )
		{
			for_each( m_objects.begin(), m_objects.end(), mem_fun( &EpilObject::ReleaseCopy ) );
			throw;
		}
		m_objects.push_back( ei.GetObject() );
	}

	EpilExpressionInterpreter ei( this->GetInterpreter() );
	try
	{
		ei.Run( *itLast );
	}
	catch( ... )
	{
		for_each( m_objects.begin(), m_objects.end(), mem_fun( &EpilObject::ReleaseCopy ) );
		throw;
	}
	const EpilObjectVector & rets = ei.GetMultipleValues();
	copy( rets.begin(), rets.end(), back_inserter( m_objects ) );
}